#include <opencv2\highgui\highgui.hpp>
#include <opencv2\core\core.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\features2d\features2d.hpp>
#include <opencv2\nonfree\nonfree.hpp>
#include <iostream>
#include "myOpenCVLIB\myheader.h"
#include "myOpenCVLIB\maderfaker.h"




using namespace std;  
using namespace cv; 


void byBFMatcher(Mat img1,Mat img2);
void byFLANNMatcher(Mat img1,Mat img2);

int main(){
	maderfaker::ImgShower im;

	Mat img1 = imread(MEDIUM_CENTER, CV_LOAD_IMAGE_GRAYSCALE);
	Mat img2 = imread(MEDIUM_SHIFTED, CV_LOAD_IMAGE_GRAYSCALE);
	

	if(img1.data == 0 || img2.data == 0){
		cout <<"cant load dataa";
		return -1;
	}

	im.sh("center",img1);
	im.sh("shifted",img2);

	byFLANNMatcher(img1, img2);

	
	getchar();
	return 0;
}


void byFLANNMatcher(Mat img1,Mat img2){
	SurfFeatureDetector detector(10);
	vector<KeyPoint> keypoints1,keypoints2;
	
	detector.detect(img1,keypoints1);
	detector.detect(img2,keypoints2);

	SurfDescriptorExtractor extractor;
	Mat descript1,descript2;
	extractor.compute(img1, keypoints1, descript1);
	extractor.compute(img2, keypoints2, descript2);
	
	FlannBasedMatcher matcher;
	vector<DMatch> matches;
	matcher.match(descript1, descript2, matches);

	double maxDistance = 0, minDistance = 100;

	for(int i=0; i< descript1.rows;i++){
		double distance = matches[i].distance;
		if(distance < minDistance){
			minDistance = distance;
		}
		if(distance > maxDistance){
			maxDistance = distance;
		}
	}

	cout << "max dist " << maxDistance;
	cout << "min dist " << minDistance;
	
	vector<DMatch> goodMatches;
	for(int i=0;i<descript1.rows;i++){
		if(matches[i].distance <= MAX(2*minDistance, 0.02)){
			goodMatches.push_back(matches[i]);
		}
	}

	Mat result;
	drawMatches(img1, keypoints1
		,img2, keypoints2
		,goodMatches
		, result
		, Scalar::all(-1)
		, Scalar::all(-1)
		, vector<char>()
		, DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);

	//im.sh("result",result);
	imwrite(IMAGES_DIR + string("smallResultFLANNMatch.png"),result);
	cout << " maches size :" << matches.size()<<endl;
	cout << " good size :" << goodMatches.size()<<endl;
}

void byBFMatcher(Mat img1,Mat img2){
	
	
	SurfFeatureDetector detector(10);
	vector<KeyPoint> keypoints1,keypoints2;
	
	detector.detect(img1,keypoints1);
	detector.detect(img2,keypoints2);

	SurfDescriptorExtractor extractor;
	Mat descript1,descript2;
	extractor.compute(img1, keypoints1, descript1);
	extractor.compute(img2, keypoints2, descript2);
	
	/*im.sh("descript1",descript1);
	im.sh("descript2",descript2);*/

	BFMatcher matcher(NORM_L2);
	vector<DMatch> matches;
	matcher.match(descript1, descript2,matches);

	Mat result;
	drawMatches(img1,keypoints1,img2, keypoints2,matches, result);

	//im.sh("result",result);
	
	imwrite(IMAGES_DIR + string("smallResultBFMatch.png"),result);

	cout << " maches size :" << matches.size();


}